package com.leyou.service.impl;

import com.leyou.common.utils.CodecUtils;
import com.leyou.common.utils.NumberUtils;
import com.leyou.mapper.UserMapper;
import com.leyou.pojo.User;
import com.leyou.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private AmqpTemplate amqpTemplate;

    //这个是将短信验证码存到Redis中的前缀,没有什么影响,只是方便阅读
    static final String KEY_PREFIX = "user:code:phone:";

    static final Logger logger = LoggerFactory.getLogger(UserService.class);

    @Override
    public Boolean checkUserData(String data, Integer type) {
        User record = new User();
        switch (type) {
            case 1:
                record.setUsername(data);
                break;
            case 2:
                record.setPassword(data);
                break;
        }
        //查到了说明已经注册了,这时候用户不能在注册了.
        int i = this.userMapper.selectCount(record);
        return i != 1;
    }

    @Override
    public void sendVerifierCode(String phone) {
        //发送一个6位的随机验证码
        String code = NumberUtils.generateCode(6);
        try {
            Map msg = new HashMap();
            msg.put("phone", phone);
            msg.put("code", code);
            //调用消息中间件发送消息
            this.amqpTemplate.convertAndSend("ly.sms.exchange", "sms.verify.code", msg);
            //保存消息到Redis中,设置到期时间为5分钟
            redisTemplate.opsForValue().set(KEY_PREFIX + phone, code, 5, TimeUnit.MINUTES);
        } catch (AmqpException e) {
            logger.error("发送短信失败,手机{},验证码{}", phone, code);
            e.printStackTrace();
        }
    }

    @Override
    public Boolean register(User user, String code) {
        //从Redis中取出code,与传递过来的code进行比较
        String key = KEY_PREFIX + user.getPhone();
        String codeRedis = redisTemplate.opsForValue().get(key);
        if (StringUtils.isBlank(codeRedis) && !code.equals(codeRedis)) {
            return false;
        }
        //满足条件就将数据保存到数据库中
        user.setCreated(new Date());
        //生成盐
        String salt = CodecUtils.generateSalt();
        user.setSalt(salt);
        //加盐加密
        String codeMd5 = CodecUtils.md5Hex(user.getPassword(), salt);
        user.setPassword(codeMd5);
        //保存
        boolean bool = userMapper.insertSelective(user) == 1;
        //删除Redis中的code,减少空间的占用
        if (bool) {
            try {
                this.redisTemplate.delete(key);
            } catch (Exception e) {
                logger.error("验证码删失败,手机号是{},验证码是{}", user.getPhone(), code);
                e.printStackTrace();
            }
        }
        return bool;
    }

    @Override
    public User queryUser(String username, String password) {
        User user = new User();
        user.setUsername(username);
        //校验用户名
        User record = this.userMapper.selectOne(user);
        if (record == null) {
            return null;
        }
        //验证密码(取出数据库中的密码,然后将传进来的密码进行加盐加密,两者相比较)
        String recordPassword = record.getPassword();
        String salt = record.getSalt();
        String passwordMd5 = CodecUtils.md5Hex(password, salt);
        if (!recordPassword.equals(passwordMd5)) {
            return null;
        }
        return record;
    }
}
